﻿
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
#if LOCALIZATION_ENABLE_TEXTMESHPRO
using TMPro;
#endif
using UnityEngine; 
using UnityEngine.UI;

namespace XFGameFramework.Localization
{

    public enum ComponentType 
    { 
        Text,
        TextMesh,
        Other,
#if LOCALIZATION_ENABLE_TEXTMESHPRO
        TextMeshProUGUI,
        TextMeshPro,
#endif
    }

    public enum AppendType 
    {
        ID,
        String
    }

    [Serializable]
    public struct AppendData
    {
        public AppendType type;
        public int id;
        public string str;

        public string richText; 
    }

    /// <summary>
    /// 文本本地化组件
    /// </summary>
    [HelpURL("https://gitee.com/xianfengkeji/xfgame-framework.localization/blob/master/Documentation~/ClassApi/LocalizeString.md")]
    public class LocalizeString : LocalizeBase
    {

        #region 字段 

        /// <summary>
        /// 显示文本的组件类型
        /// </summary>
        [SerializeField]
        [Header("显示文本的组件类型")]
        [Tooltip("显示文本的组件类型")]
        private ComponentType componentType;

        /// <summary>
        /// 组件类名(含命名空间)
        /// </summary>
        [SerializeField]
        [Header("组件类名(含命名空间)")]
        [Tooltip("组件类名(含命名空间)")]
        private string componentFullName;

        /// <summary>
        /// 字段名称
        /// </summary>
        [SerializeField]
        [Header("字段名称")]
        [Tooltip("字段名称")]
        private string fieldName;

#if LOCALIZATION_ENABLE_TEXTMESHPRO 

        private TextMeshProUGUI textMeshProUGUI; 
        private TextMeshPro textMeshPro;

#endif

        private Text text;
        private TextMesh textMesh;

        private Component otherComponent; 
        private PropertyInfo propertyOther; 
        private FieldInfo fieldOther;

        [SerializeField]
        [Tooltip("参数")]
        private List<AppendData> args = null;

        [SerializeField]
        [Tooltip("附加数据")]
        private List<AppendData> appends = null;

        private StringBuilder stringBuilder = null;

        #endregion


        #region 属性

        /// <summary>
        /// 附加数据
        /// </summary>
        public List<AppendData> Appends => appends;

        #endregion


        #region 生命周期

        private void Reset()
        {
#if LOCALIZATION_ENABLE_TEXTMESHPRO

            textMeshProUGUI = GetComponent<TextMeshProUGUI>();
            if (textMeshProUGUI != null)
                componentType = ComponentType.TextMeshProUGUI;

            textMeshPro = GetComponent<TextMeshPro>();
            if (textMeshPro != null)
                componentType = ComponentType.TextMeshPro;

#endif

            text = GetComponent<Text>();
            if (text != null)
                componentType = ComponentType.Text;

            textMesh = GetComponent<TextMesh>();
            if (textMesh != null)
                componentType = ComponentType.TextMesh; 
        }

        private void Awake()
        {
            Init(); 
        }
         
        #endregion


        #region 方法

        private void Init()
        {

            switch (componentType)
            {
#if LOCALIZATION_ENABLE_TEXTMESHPRO 
                case ComponentType.TextMeshProUGUI: 
                    textMeshProUGUI = GetComponent<TextMeshProUGUI>(); 
                    break;
                case ComponentType.TextMeshPro: 
                    textMeshPro = GetComponent<TextMeshPro>();
                    break; 
#endif

                case ComponentType.Text: 
                    text = GetComponent<Text>(); 
                    break;
                case ComponentType.TextMesh: 
                    textMesh = GetComponent<TextMesh>(); 
                    break;
                case ComponentType.Other:

                    otherComponent = GetComponent(componentFullName);

                    if (otherComponent != null) 
                    {
                        propertyOther = otherComponent.GetType().GetProperty(fieldName);
                        fieldOther = otherComponent.GetType().GetField(fieldName);
                    }

                    break; 
            }
             

        }


        protected override void OnLanguageValueChange()
        {  
            SetValue();
        }
         
        private void SetValue()
        { 
            switch (componentType)
            {

#if LOCALIZATION_ENABLE_TEXTMESHPRO

                case ComponentType.TextMeshProUGUI:

#if UNITY_EDITOR
                    if (!Application.isPlaying && textMeshProUGUI == null)
                        Init();
#endif

                    if (textMeshProUGUI != null)
                        textMeshProUGUI.text = GetString();

                    break;
                case ComponentType.TextMeshPro:

#if UNITY_EDITOR
                    if (!Application.isPlaying && textMeshPro == null)
                        Init();
#endif

                    if (textMeshPro != null)
                        textMeshPro.text = GetString();

                    break;
#endif

                case ComponentType.Text:

#if UNITY_EDITOR
                    if (!Application.isPlaying && text == null)
                        Init();
#endif

                    if (text != null)
                        text.text = GetString();

                    break;
                case ComponentType.TextMesh:


#if UNITY_EDITOR
                    if (!Application.isPlaying && textMesh == null)
                        Init();
#endif

                    if (textMesh != null)
                        textMesh.text = GetString();

                    break;
                case ComponentType.Other:

#if UNITY_EDITOR
                    if (!Application.isPlaying && otherComponent == null)
                        Init();
#endif

                    if (otherComponent != null)
                    {
                        if(propertyOther != null)
                            propertyOther.SetValue(otherComponent, GetString());
                        if(fieldOther != null)
                            fieldOther.SetValue(otherComponent, GetString()); 
                    }

                    break; 
            }



#if UNITY_EDITOR
            if (!Application.isPlaying) 
            {
                // 刷新
                if (gameObject.activeSelf)
                {
                    gameObject.SetActive(false);
                    gameObject.SetActive(true);
                } 
            }
#endif
        }

        /// <summary>
        /// 获取显示的文本
        /// </summary>
        /// <returns></returns>
        public string GetString()
        { 

            LanguageInfo info = LocalizationManager.GetLanguageInfo(ID);
             
            if (info != null && info.type != MultiLanguageType.String) 
            {
                Debug.LogWarningFormat("多语言配置:{0}不是String类型,请调整后再试!",ID);
                return string.Empty;
            }

            string str = string.Empty;

            if (info != null)
                str = info.str;
              
            if (stringBuilder == null)
                stringBuilder = new StringBuilder();

            stringBuilder.Clear();

            object[] args = GetArgs(); 

            if (args != null && args.Length != 0)  
                stringBuilder.Append(string.Format( str,args)); 
            else
                stringBuilder.Append(str);

            if (appends != null && appends.Count > 0) 
            { 
           
                foreach (var item in appends)
                {
                    if (!string.IsNullOrEmpty(item.richText) && item.richText.Contains("{0}")) 
                        stringBuilder.Append(string.Format( item.richText,GetAppendString(item))); 
                    else  
                        stringBuilder.Append( GetAppendString(item)); 
                }
            }


            return stringBuilder.ToString();
        }

        /// <summary>
        /// 附加其他文本
        /// </summary>
        /// <param name="id">文本id</param>
        /// <param name="richText">富文本(示例:*{0}* *代表富文本标签,一定要有一个{0},文本占位符)</param>
        public void Append(int id,string richText = null) 
        {
            if (appends == null)
                appends = new List<AppendData>();

            AppendData data = new AppendData();
            data.id = id;
            data.type = AppendType.ID;
            data.richText = richText;
            data.str = null;
            appends.Add(data);

            OnLanguageValueChange();
        }

        /// <summary>
        /// 附加其他文本
        /// </summary>
        /// <param name="str">文本值</param>
        /// <param name="richText">富文本(示例:*{0}* *代表富文本标签,一定要有一个{0},文本占位符)</param>
        public void Append(string str, string richText = null) 
        {
            if (appends == null)
                appends = new List<AppendData>();

            AppendData data = new AppendData();
            data.id = 0;
            data.type = AppendType.String;
            data.richText = richText;
            data.str = str;

            appends.Add(data);

            OnLanguageValueChange();
        }

        /// <summary>
        /// 清空所有附加的数据
        /// </summary>
        public void ClearAppend() 
        {
            if (appends == null || appends.Count == 0)
                return;
            
            appends.Clear();
            OnLanguageValueChange();
        }

        private string GetAppendString(AppendData data) 
        {
            string v = string.Empty;

            switch (data.type)
            {
                case AppendType.ID:
                    LanguageInfo i = LocalizationManager.GetLanguageInfo(data.id);
                    if (i != null) v = i.str;
                    break;
                case AppendType.String:
                    if (!string.IsNullOrEmpty(data.str))
                        v = data.str;
                    break;
            }

            if (string.IsNullOrEmpty(data.richText))
                return v;
            else
                return string.Format(data.richText, v);
        }

        /// <summary>
        /// 查询参数
        /// </summary>
        /// <returns></returns>
        public string[] GetArgs() 
        {
            if (args == null || args.Count == 0)
                return null;


            string[] strs = new string[args.Count];

            for (int i = 0; i < args.Count; i++) 
            {
                strs[i] = GetAppendString(args[i]);
            }

            return strs;
        }


        /// <summary>
        /// 设置参数
        /// </summary>
        /// <param name="data">参数内容</param>
        public void SetArgs(IList<AppendData> data) 
        {
            if (data == null || data.Count == 0)
                return;

            if(args == null) 
                args = new List<AppendData>();

            args.Clear();
            args.AddRange(data);
            OnLanguageValueChange();
        }

        #endregion

    }

}

